package com.Apo1o.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.lang.reflect.Type;

@Slf4j
@ControllerAdvice
@RequiredArgsConstructor
public class BodyAdvice extends RequestBodyAdviceAdapter {

    private final ObjectMapper objectMapper;

    /**
     * 判断给定的转换器类型是否支持指定的方法参数和目标类型。
     *
     * @param methodParameter 指定的方法参数，包含方法的返回类型和参数类型等信息。
     * @param targetType 方法参数的目标类型。
     * @param converterType 转换器的类型。
     * @return 总是返回true，表示该转换器类型支持所有方法参数和目标类型。
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    /**
     * 在读取HTTP请求体后执行的逻辑。
     * 这个方法会记录请求体的内容，然后调用父类的同名方法进行后续处理。
     *
     * @param body 从HTTP请求中读取到的请求体对象。
     * @param inputMessage 表示HTTP请求的消息对象。
     * @param parameter 方法参数的描述，指明了参数的类型和位置。
     * @param targetType 请求体对象的目标类型。
     * @param converterType 用于转换HTTP消息的转换器类型。
     * @return 经过可能的修改后的请求体对象。
     * @throws Exception 如果处理过程中发生异常。
     */
    @Override
    @SneakyThrows
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
                                Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 记录请求体信息
        log.info("[Request body]: {}", objectMapper.writeValueAsString(body));
        return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
    }
}
